    /**********************************************************
    ***             Processing.h: EXI decoder               ***
    **********************************************************/


#ifndef __PROCESSING_H__
#define __PROCESSING_H__


#define DEBUGMODE
// switch between PC debug mode (console printfs, tags are stored as Strings)
// and uC release mode (URI & LocalName counters, only values are stored)


#ifdef DEBUGMODE
#include <stdio.h>
#include <stdlib.h>
#endif


/****** include generated FSM header file ******/

//#include "1_soap.h"
//#include "2_soap.h"
//#include "3_soap.h"
//#include "4_soap.h"
//#include "5_soap.h"
//#include "6_soap.h"
//#include "7_soap.h"
//#include "8_soap.h"
//#include "9_soap.h"
//#include "10_soap.h"

#include "1_soap.h"

/***********************************************/


/********* data type definitions ***************/

#ifdef DEBUGMODE

struct String {
	unsigned char* str;
	unsigned char length;
};

typedef struct String String;


struct QName {
	const String* uri;
	const String* localName;
};

typedef struct QName QName;

#endif


struct date {
    unsigned char day;
    unsigned char month;
    int year;
};

typedef struct date date;



typedef unsigned char Datatype;

// data type makros
#define NONE      		0
#define BOOLEAN   		1
#define DATETIME  		2
#define INTEGER   		3
#define STRING    		4
#define UNSIGNED_LONG	5
#define LIST_TYPE		6
#define ENUMERATION 	7


// global variables for payload values
unsigned char* string_value;
int int_value;
unsigned int ulong_value;
unsigned int bool_value;
date date_value;


Datatype datatype;				// current data type of incoming generic AT(*) event content
Datatype list_datatype;			// data type of all elements in decoded LIST

unsigned char enum_codelength;	// number of bits for position index of current incoming ENUMERATION
unsigned char enum_position;	// position index of current ENUMERATION value (encoded in EXI file)


#ifdef DEBUGMODE
QName curr_qname;
#endif


#define false 0
#define true  1


/********* String Table definitions ***************/

#ifdef DEBUGMODE

#define URI_XML		"http://www.w3.org/XML/1998/namespace"
#define URI_XS		"http://www.w3.org/2001/XMLSchema"
#define URI_XSI		"http://www.w3.org/2001/XMLSchema-instance"

#define PREFIX_XML "xml"
#define PREFIX_XSI "xsi"

#define LOCALNAMES_XML_SIZE 4
extern const char* LOCALNAMES_XML[];

#define LOCALNAMES_XSI_SIZE 2
extern const char* LOCALNAMES_XSI[];

#define LOCALNAMES_XS_SIZE 46
extern const char* LOCALNAMES_XS[];

struct LocalNames_Entry {
	String value; // local name string
};

struct LocalNames_Table {
	struct LocalNames_Entry* entries; // contains LocalNames for a specific URI
	unsigned char entryCount; // number of entries
};

typedef struct LocalNames_Table LocalNames_Table;

struct Prefix_Entry {
	String value; // prefix string
};

struct Prefix_Table {
	struct Prefix_Entry* entries; // contains prefixes for a specific URI
	unsigned char entryCount; // number of entries
};

typedef struct Prefix_Table Prefix_Table;

struct URI_Entry {
	Prefix_Table* pTable; // URI prefixes
	LocalNames_Table* lnTable; // LocalNames under URI
	String value; // URI string
};

struct URI_Table {
	struct URI_Entry* entries; // contains all namespace URIs
	unsigned char entryCount; // number of entries
};

typedef struct URI_Table URI_Table;


struct URI_Table   *uriTable;   // global URI table


void create_URI_Table(URI_Table** uTable);
void create_Prefix_Table(Prefix_Table** pTable);
void create_LocalNames_Table(LocalNames_Table** lTable);


unsigned char URI_Table_insertEntry(URI_Table* uTable, String uri);
unsigned char LocalNames_Table_insertEntry(LocalNames_Table* lTable, String localname);
void Prefix_Table_insertEntry(Prefix_Table* pTable, String prefix);


// prints URI table and related string tables to console, for testing
void URI_Table_show();

#endif


#define MAX_STRING_LENGTH	100
unsigned char str_buffer[MAX_STRING_LENGTH];  // buffer for String values


#define MAX_URIS	12	// max number of namespaces

unsigned char uricount;					// number of known URIs
unsigned char localnamecount[MAX_URIS];	// number of known local names for specific URI


// global value buffer of fixed size
unsigned char str_values_global[512];
// lengths of stored global values
unsigned char str_values_global_lengths[64];
// number of elements in str_values_global
unsigned char str_values_global_num;

void reset_str_values_global(void);
unsigned char insert_str_value_global(unsigned char *str, unsigned char strlen, unsigned char uriID, unsigned char lnID);
unsigned char get_str_value_global(unsigned char id, unsigned char *str);
unsigned char get_str_value_local(unsigned char uriID, unsigned char lnID, unsigned char *str);


// URI & LocalName IDs of current tag QName, used to assign values to tags
// and to determine next FSM after generic Event, to be used in future callbacks
unsigned char curr_uriID;
unsigned char curr_lnID;


/********* processing functions ***************/

void Processing(unsigned char *inbuffer);

void setAlignment(unsigned char alig);
unsigned char getAlignment();

void set_strict_mode(unsigned char mode);
unsigned char get_strict_mode();


#ifdef DEBUGMODE
unsigned char str_length(const char *strptr);
#endif


unsigned char ld(unsigned char value);

void getbit(unsigned char *Byte, unsigned char Anz);

void getQName();

// data type decoding functions

unsigned int getUint();
unsigned int getnBitUint(unsigned char n);

#ifdef DEBUGMODE
String getSTRING_unknownLength();
#endif

unsigned char* getSTRINGValue();
void getSTRING_knownLength(unsigned char str_length);

date getDATETIME();
unsigned int getBOOLEAN();
int getINTEGER();

// decodes content of generic AT(*) events, used for LIST & ENUM data types
void getData();


#endif // __PROCESSING_H__

